home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / delphi.swg / 0199_Creating a DataAware Control for Browsin.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-11-29  |  7.8 KB  |  296 lines

  1.  
  2. OVERVIEW
  3.  
  4.   This document describes minimal steps necessary to create a 
  5. data-aware browsing component that displays data for a single 
  6. field.  The example component is a panel with DataSource and 
  7. DataField properties similar to the TDBText component.  See the 
  8. Component Writer's Guide "Making a Control Data-Aware" for further 
  9. examples.
  10.  
  11.  
  12. WHO SHOULD USE THIS DOCUMENT
  13.  
  14.   To get the best use of this document, you should be familiar 
  15. with data aware control functionality and fundamental component 
  16. creation tasks, such as 
  17.  
  18. -- deriving components from existing components
  19.  
  20. -- overriding constructor and destructors
  21.  
  22. -- creating new properties
  23.  
  24. -- getting and setting property values
  25.  
  26. -- assigning event handlers
  27.  
  28.  
  29.  
  30. BASIC STEPS TO CREATE A DATA-BROWSING COMPONENT
  31.  
  32. -- Create or derive a component that allows the display, but
  33.    not the entry of data.  For instance, you could use a 
  34.    TMemo with ReadOnly set to true.  In the example
  35.    outlined in this document, we'll use a TCustomPanel.
  36.    The TCustomPanel will allow display, but not data entry.
  37.  
  38. -- Add a data-link object to your component.  This object
  39.    manages communication between the component and the 
  40.    database table.
  41.  
  42. -- Add DataField and DataSource properties to the component. 
  43.  
  44. -- Add methods to get and set the DataField and DataSource.
  45.  
  46. -- Add a DataChange method the component to handle the 
  47.    data-link object's OnDataChange event.
  48.  
  49. -- Override the component constructor to create the datalink
  50.    and hook up the DataChange method.
  51.  
  52. -- Override the component destructor to cleanup the datalink.
  53.  
  54.  
  55.  
  56. CREATING THE TDBPANEL
  57.  
  58. -- Create or derive a component that allows the display, but
  59.    not the entry of data.  We'll be using a TCustomPanel as 
  60.    a starting point for this example.
  61.  
  62.    Choose the appropriate menu option to create a new component (this
  63.    will vary between editions of Delphi), and specify TDBPanel
  64.    as the class name, and TCustomPanel as the Ancestor type.
  65.    You may specify any palette page.
  66.  
  67. -- Add DB and DBTables to your Uses clause.
  68.  
  69. -- Add a data-link object to the components private section. 
  70.    This example will display data for a single field, so we will
  71.    use a TFieldDataLink to provide the connection between our new
  72.    component and a DataSource.  Name the new data-link object 
  73.    FDataLink.
  74.  
  75.   { example }
  76.   private
  77.     FDataLink: TFieldDataLink;
  78.  
  79. -- Add DataField and DataSource properties to the component. We
  80.    will add supporting code for the get and set methods in
  81.    following steps.    
  82.    
  83.    Note: Our new component will have DataField and DataSource
  84.    properties and FDataLink will also have its own DataField and 
  85.    Datasource properties.
  86.  
  87.   { example }
  88.   published
  89.     property DataField: string
  90.       read   GetDataField
  91.       write  SetDataField;
  92.     property DataSource: TDataSource
  93.       read   GetDataSource
  94.       write  SetDataSource;
  95.  
  96. -- Add private methods to get and set the DataField and DataSource 
  97.    property values to and from the DataField and DataSource for
  98.    FDataLink.
  99.  
  100.   { example }
  101.   private
  102.     FDataLink: TFieldDataLink;
  103.     function GetDataField: String;
  104.     function GetDataSource: TDataSource;
  105.     procedure SetDataField(Const Value: string);
  106.     procedure SetDataSource(Value: TDataSource);
  107.     .
  108.     .
  109.   implementation    
  110.     .
  111.     .
  112.   function TDBPanel.GetDataField: String;
  113.   begin
  114.     Result := FDataLink.FieldName;
  115.   end;
  116.  
  117.   function TDBPanel.GetDataSource: TDataSource;
  118.   begin
  119.     Result := FDataLink.DataSource;
  120.   end;
  121.  
  122.   procedure TDBPanel.SetDataField(Const Value: string);
  123.   begin
  124.     FDataLink.FieldName := Value;
  125.   end;
  126.  
  127.   procedure TDBPanel.SetDataSource(Value: TDataSource);
  128.   begin
  129.     FDataLink.DataSource := Value;
  130.   end;
  131.    
  132. -- Add a private DataChange method to be assigned to the 
  133.    datalink's OnDataChange event.  In the DataChange method
  134.    add code to display actual database field data provided
  135.    by the data-link object.  In this example, we assign
  136.    FDataLink's field value to the panel's caption.
  137.  
  138.   { example }
  139.   private
  140.     .
  141.     .
  142.     procedure DataChange(Sender: TObject);
  143.  
  144.   implementation
  145.     .
  146.     .
  147.   procedure TDBPanel.DataChange(Sender: TObject);
  148.   begin
  149.     if FDataLink.Field = nil then
  150.       Caption := '';
  151.     else
  152.       Caption := FDataLink.Field.AsString;
  153.   end;
  154.  
  155.  
  156. -- Override the component constructor Create method.  In the 
  157.    implementation of Create, create the FDataLink object, and 
  158.    assign the private DataChange method to FDataLink's 
  159.    OnDataChange event.
  160.  
  161.   { example }
  162.   public
  163.     constructor Create(AOwner: TComponent); override;
  164.     .
  165.     .
  166.   implementation
  167.     .
  168.     .
  169.   constructor TMyDBPanel.Create(AOwner: TComponent);
  170.   begin
  171.     inherited Create(AOwner);
  172.     FDataLink := TFieldDataLink.Create;
  173.     FDataLink.OnDataChange := DataChange;
  174.   end;
  175.  
  176. -- Override the component destructor Destroy method.  In the 
  177.    implementation of Destroy, set OnDataChange to nil (avoids a
  178.    GPF), and free FDatalink.
  179.    
  180.   { example }
  181.   public
  182.     .
  183.     .
  184.     destructor Destroy; override;
  185.     .
  186.     .
  187.   implementation
  188.     .
  189.     .
  190.   destructor TDBPanel.Destroy;
  191.   begin
  192.     FDataLink.OnDataChange := nil;
  193.     FDataLink.Free;
  194.     inherited Destroy;
  195.   end;
  196.  
  197. -- Save the unit and install the component (see the Users 
  198.    Guide, and the Component Writers Guide for more on 
  199.    saving units and installing components).  
  200.  
  201. -- To test the functionality of the component, add a TTable, 
  202.    TDatasource, TDBNavigator and TDBPanel to a form.  Set the 
  203.    TTable DatabaseName and Tablename to 'DBDemos' and 'BioLife',
  204.    and the Active property to True. Set the TDatasource 
  205.    Dataset property to Table1.  Set the TDBNavigator and 
  206.    TDBPanel DataSource property to Datasource1.  The TDBpanel 
  207.    DataField name should be set as 'Common_Name'.  Run the 
  208.    application and use the navigator to move between records to 
  209.    demonstrate the TDBPanel's ability to detect the change in 
  210.    data and display the appropriate field value.
  211.    
  212.  
  213. FULL SOURCE LISTING
  214.  
  215. unit Mydbp;
  216.  
  217. interface
  218.  
  219. uses
  220.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  221.   Forms, Dialogs, ExtCtrls, DB, DBTables;
  222.  
  223. type
  224.   TDBPanel = class(TCustomPanel)
  225.   private
  226.     FDataLink: TFieldDataLink;
  227.     function GetDataField: String;
  228.     function GetDataSource: TDataSource;
  229.     procedure SetDataField(Const Value: string);
  230.     procedure SetDataSource(Value: TDataSource);
  231.     procedure DataChange(Sender: TObject);
  232.   public
  233.     constructor Create(AOwner: TComponent); override;
  234.     destructor Destroy; override;
  235.   published
  236.     property DataField: string
  237.       read   GetDataField
  238.       write  SetDataField;
  239.     property DataSource: TdataSource
  240.       read   GetDataSource
  241.       write  SetDataSource;
  242.   end;
  243.  
  244.   procedure Register;
  245.  
  246. implementation
  247.  
  248.   procedure Register;
  249.   begin
  250.     RegisterComponents('Samples', [TDBPanel]);
  251.   end;
  252.  
  253.   function TDBPanel.GetDataField: String;
  254.   begin
  255.     Result := FDataLink.FieldName;
  256.   end;
  257.  
  258.   function TDBPanel.GetDataSource: TDataSource;
  259.   begin
  260.     Result := FDataLink.DataSource;
  261.   end;
  262.  
  263.   procedure TDBPanel.SetDataField(Const Value: string);
  264.   begin
  265.     FDataLink.FieldName := Value;
  266.   end;
  267.  
  268.   procedure TDBPanel.SetDataSource(Value: TDataSource);
  269.   begin
  270.     FDataLink.DataSource := Value;
  271.   end;
  272.  
  273.   procedure TDBPanel.DataChange(Sender: TObject);
  274.   begin
  275.     if FDataLink.Field = nil then
  276.       Caption := ''
  277.     else
  278.       Caption := FDataLink.Field.AsString;
  279.   end;
  280.  
  281.   constructor TDBPanel.Create(AOwner: TComponent);
  282.   begin
  283.     inherited Create(AOwner);
  284.     FDataLink := TFieldDataLink.Create;
  285.     FDataLink.OnDataChange := DataChange;
  286.   end;
  287.  
  288.   destructor TDBPanel.Destroy;
  289.   begin
  290.     FDataLink.Free;
  291.     FDataLink.OnDataChange := nil;
  292.     inherited Destroy;
  293.   end;
  294.  
  295. end.
  296.